Import Library & data¶

In [9]:
import SPIX
import scanpy as sc
import squidpy as sq
import matplotlib.pyplot as plt
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/tqdm_joblib/__init__.py:4: TqdmExperimentalWarning: Using `tqdm.autonotebook.tqdm` in notebook mode. Use `tqdm.tqdm` instead to force console mode (e.g. in jupyter console)
  from tqdm.autonotebook import tqdm
In [10]:
# adata = sc.read_h5ad('/path/to/your/dir/Anndata.h5ad')
# adata = sq.datasets.slideseqv2()
### Use raw counts if you can use
# adata.X = adata.layers['count'].copy()

### Cal Original MoranI
# sc.pp.filter_genes(adata, min_cells=1)
# sc.pp.normalize_total(adata)
# sc.pp.log1p(adata)

# sq.gr.spatial_neighbors(adata)
# sq.gr.spatial_autocorr(adata, mode="moran", genes=adata.var_names)
# adata.uns["moranI"][adata.uns["moranI"]['I']>0.1].head()
# original_moranI = adata.uns["moranI"][adata.uns["moranI"]['I']>0.1].copy()

### Use raw counts if you can use
# adata.X = adata.layers['count'].copy()
In [11]:
adata
Out[11]:
AnnData object with n_obs × n_vars = 41786 × 17733
    obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
    var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
    uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI'
    obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial'
    obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'

Generate Embeddings & Tiles¶

In [12]:
adata = SPIX.tm.generate_embeddings(
    adata,
    dim_reduction='PCA',
    normalization='none',  # already normalized data
    dimensions=30,
    nfeatures=2000,
    n_jobs=16,
    filter_grid=1,
    filter_threshold=0.995,
    tensor_resolution=1,
    chunksize=3000,
    verbose=True
    )
2025-04-09 03:40:43,545 - INFO - Starting generate_embeddings...
2025-04-09 03:40:43,546 - INFO - Tiles not found. Generating tiles...
2025-04-09 03:40:43,546 - INFO - Starting generate_tiles...
2025-04-09 03:40:43,549 - INFO - Original coordinates: (41786, 2)
2025-04-09 03:40:43,550 - INFO - Performing Voronoi tessellation...
2025-04-09 03:40:43,939 - INFO - Voronoi tessellation completed.
2025-04-09 03:40:43,940 - INFO - Filtering tiles...
Calculating Voronoi region areas: 100%|██████████| 41786/41786 [00:01<00:00, 20974.54it/s]
Filtering tiles by area: 100%|██████████| 41738/41738 [00:00<00:00, 2755491.10it/s]
2025-04-09 03:40:45,963 - INFO - Filtered regions: 41529, Filtered coordinates: (41529, 2)
2025-04-09 03:40:45,964 - INFO - Rasterising tiles...
Rasterising tiles: 100%|██████████| 41529/41529 [00:08<00:00, 4939.68it/s]
2025-04-09 03:40:58,265 - INFO - Rasterisation completed. Number of tiles: 18401456
2025-04-09 03:40:58,266 - INFO - Tiles have been stored in adata.uns['tiles'].
2025-04-09 03:40:59,372 - INFO - adata has been subset from 41786 to 41529 observations based on filtered tiles.
2025-04-09 03:40:59,373 - INFO - generate_tiles completed.
2025-04-09 03:40:59,388 - INFO - Processing counts...
2025-04-09 03:40:59,389 - INFO - Processing counts with method: none
2025-04-09 03:40:59,616 - INFO - Counts processing completed.
2025-04-09 03:40:59,642 - INFO - Embedding latent space...
2025-04-09 03:40:59,643 - INFO - Embedding latent space using PCA...
2025-04-09 03:41:00,599 - INFO - Latent space embedding completed.
2025-04-09 03:41:00,601 - INFO - generate_embeddings completed.
In [13]:
SPIX.pl.image_plot(
    adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=10,    # Adjust point size here
    origin=True
)
No description has been provided for this image

Image Processing¶

Smooth Image¶

In [14]:
SPIX.ip.smooth_image(
    adata,
    dimensions = list(range(30)),
    sigma=10,
    n_jobs=30,
    multi_method='loky'
)
2025-04-09 03:41:00,928 - INFO - Starting smooth_image...
2025-04-09 03:41:00,933 - INFO - Using embedding 'X_embedding' with shape (41529, 30).
2025-04-09 03:41:01,146 - INFO - Shifting coordinates by (-691, -468) to start from 0.
2025-04-09 03:41:01,565 - INFO - Image size: width=5294, height=5258
2025-04-09 03:41:01,566 - INFO - Starting parallel processing of dimensions...
Filling NaNs:   0%|          | 0/30 [00:00<?, ?it/s]
  0%|          | 0/30 [00:00<?, ?it/s]
2025-04-09 03:41:16,057 - INFO - Filling NaNs for dimension 0...
2025-04-09 03:41:17,016 - INFO - Filling NaNs for dimension 1...
2025-04-09 03:41:18,052 - INFO - Filling NaNs for dimension 2...
2025-04-09 03:41:18,410 - INFO - Filling NaNs for dimension 3...
2025-04-09 03:41:19,266 - INFO - Filling NaNs for dimension 4...
2025-04-09 03:41:20,313 - INFO - Filling NaNs for dimension 5...
2025-04-09 03:41:20,916 - INFO - Filling NaNs for dimension 6...
2025-04-09 03:41:22,112 - INFO - Filling NaNs for dimension 7...
2025-04-09 03:41:22,691 - INFO - Filling NaNs for dimension 8...
2025-04-09 03:41:24,143 - INFO - Filling NaNs for dimension 9...
2025-04-09 03:41:24,743 - INFO - Filling NaNs for dimension 10...
2025-04-09 03:41:25,471 - INFO - Filling NaNs for dimension 11...
2025-04-09 03:41:26,394 - INFO - Filling NaNs for dimension 12...
2025-04-09 03:41:26,892 - INFO - Filling NaNs for dimension 13...
2025-04-09 03:41:28,026 - INFO - Filling NaNs for dimension 14...
2025-04-09 03:41:28,657 - INFO - Filling NaNs for dimension 15...
2025-04-09 03:41:30,132 - INFO - Filling NaNs for dimension 17...
2025-04-09 03:41:30,517 - INFO - Filling NaNs for dimension 16...
2025-04-09 03:41:31,213 - INFO - Filling NaNs for dimension 18...
2025-04-09 03:41:32,499 - INFO - Filling NaNs for dimension 19...
2025-04-09 03:41:33,132 - INFO - Filling NaNs for dimension 20...
2025-04-09 03:41:33,787 - INFO - Filling NaNs for dimension 21...
2025-04-09 03:41:34,803 - INFO - Filling NaNs for dimension 22...
2025-04-09 03:41:35,182 - INFO - Filling NaNs for dimension 23...
2025-04-09 03:41:36,166 - INFO - Filling NaNs for dimension 24...
2025-04-09 03:41:36,991 - INFO - Filling NaNs for dimension 25...
2025-04-09 03:41:38,269 - INFO - Filling NaNs for dimension 26...
2025-04-09 03:41:39,094 - INFO - Filling NaNs for dimension 27...
2025-04-09 03:41:39,557 - INFO - Filling NaNs for dimension 28...
2025-04-09 03:41:40,267 - INFO - Filling NaNs for dimension 29...
Filling NaNs:   0%|          | 0/30 [00:45<?, ?it/s]
Smoothing dimensions:   0%|          | 0/30 [00:00<?, ?it/s]
  0%|          | 0/30 [00:00<?, ?it/s]
2025-04-09 03:41:48,735 - INFO - Smoothing for dimension 0...
2025-04-09 03:41:48,797 - INFO - Iteration 1/1 for dimension 0.
2025-04-09 03:41:49,543 - INFO - Smoothing for dimension 1...
2025-04-09 03:41:49,599 - INFO - Iteration 1/1 for dimension 1.
2025-04-09 03:41:50,394 - INFO - Smoothing for dimension 2...
2025-04-09 03:41:50,452 - INFO - Iteration 1/1 for dimension 2.
2025-04-09 03:41:51,207 - INFO - Smoothing for dimension 3...
2025-04-09 03:41:51,351 - INFO - Iteration 1/1 for dimension 3.
2025-04-09 03:41:52,245 - INFO - Smoothing for dimension 4...
2025-04-09 03:41:52,329 - INFO - Iteration 1/1 for dimension 4.
2025-04-09 03:41:53,463 - INFO - Smoothing for dimension 5...
2025-04-09 03:41:53,525 - INFO - Iteration 1/1 for dimension 5.
2025-04-09 03:41:54,774 - INFO - Smoothing for dimension 6...
2025-04-09 03:41:54,901 - INFO - Iteration 1/1 for dimension 6.
2025-04-09 03:41:55,840 - INFO - Smoothing for dimension 7...
2025-04-09 03:41:55,982 - INFO - Iteration 1/1 for dimension 7.
2025-04-09 03:41:56,882 - INFO - Smoothing for dimension 8...
2025-04-09 03:41:56,947 - INFO - Iteration 1/1 for dimension 8.
2025-04-09 03:41:57,965 - INFO - Smoothing for dimension 9...
2025-04-09 03:41:58,027 - INFO - Iteration 1/1 for dimension 9.
2025-04-09 03:41:59,137 - INFO - Smoothing for dimension 10...
2025-04-09 03:41:59,272 - INFO - Iteration 1/1 for dimension 10.
2025-04-09 03:42:00,138 - INFO - Smoothing for dimension 11...
2025-04-09 03:42:00,195 - INFO - Iteration 1/1 for dimension 11.
2025-04-09 03:42:01,191 - INFO - Smoothing for dimension 12...
2025-04-09 03:42:01,294 - INFO - Iteration 1/1 for dimension 12.
2025-04-09 03:42:02,200 - INFO - Smoothing for dimension 13...
2025-04-09 03:42:02,261 - INFO - Iteration 1/1 for dimension 13.
2025-04-09 03:42:03,219 - INFO - Smoothing for dimension 14...
2025-04-09 03:42:03,298 - INFO - Iteration 1/1 for dimension 14.
2025-04-09 03:42:04,249 - INFO - Smoothing for dimension 15...
2025-04-09 03:42:04,337 - INFO - Iteration 1/1 for dimension 15.
2025-04-09 03:42:05,381 - INFO - Smoothing for dimension 16...
2025-04-09 03:42:05,442 - INFO - Iteration 1/1 for dimension 16.
2025-04-09 03:42:06,361 - INFO - Smoothing for dimension 17...
2025-04-09 03:42:06,447 - INFO - Iteration 1/1 for dimension 17.
2025-04-09 03:42:07,433 - INFO - Smoothing for dimension 18...
2025-04-09 03:42:07,512 - INFO - Iteration 1/1 for dimension 18.
2025-04-09 03:42:08,512 - INFO - Smoothing for dimension 19...
2025-04-09 03:42:08,608 - INFO - Iteration 1/1 for dimension 19.
2025-04-09 03:42:09,615 - INFO - Smoothing for dimension 20...
2025-04-09 03:42:09,673 - INFO - Iteration 1/1 for dimension 20.
2025-04-09 03:42:10,602 - INFO - Smoothing for dimension 21...
2025-04-09 03:42:10,712 - INFO - Iteration 1/1 for dimension 21.
2025-04-09 03:42:11,656 - INFO - Smoothing for dimension 22...
2025-04-09 03:42:11,715 - INFO - Iteration 1/1 for dimension 22.
2025-04-09 03:42:13,655 - INFO - Smoothing for dimension 23...
2025-04-09 03:42:13,728 - INFO - Iteration 1/1 for dimension 23.
2025-04-09 03:42:14,899 - INFO - Smoothing for dimension 24...
2025-04-09 03:42:14,959 - INFO - Iteration 1/1 for dimension 24.
2025-04-09 03:42:15,801 - INFO - Smoothing for dimension 25...
2025-04-09 03:42:15,859 - INFO - Iteration 1/1 for dimension 25.
2025-04-09 03:42:16,783 - INFO - Smoothing for dimension 26...
2025-04-09 03:42:16,923 - INFO - Iteration 1/1 for dimension 26.
2025-04-09 03:42:17,745 - INFO - Smoothing for dimension 27...
2025-04-09 03:42:17,883 - INFO - Iteration 1/1 for dimension 27.
2025-04-09 03:42:18,774 - INFO - Smoothing for dimension 28...
2025-04-09 03:42:18,845 - INFO - Iteration 1/1 for dimension 28.
2025-04-09 03:42:19,588 - INFO - Smoothing for dimension 29...
2025-04-09 03:42:19,646 - INFO - Iteration 1/1 for dimension 29.
Smoothing dimensions:   0%|          | 0/30 [00:36<?, ?it/s]
2025-04-09 03:42:24,100 - INFO - Applying Min-Max scaling to the smoothed embeddings.
2025-04-09 03:42:24,112 - INFO - Smoothed embeddings stored in adata.obsm['X_embedding_smooth'].
2025-04-09 03:42:24,113 - INFO - Smoothing completed and embeddings updated in AnnData object.
Out[14]:
AnnData object with n_obs × n_vars = 41529 × 17733
    obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
    var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
    uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict'
    obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth'
    layers: 'log_norm'
    obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [15]:
SPIX.pl.image_plot(
    adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding_smooth',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=10,    # Adjust point size here
    origin=True
)
No description has been provided for this image

Equalize Image¶

In [16]:
SPIX.ip.equalize_image(
    adata,
    dimensions=list(range(30)),
    embedding='X_embedding_smooth',
    sleft=5,sright=5)
Starting equalization...
Equalizing dimension 0 using method 'BalanceSimplest'
Equalizing dimension 1 using method 'BalanceSimplest'
Equalizing dimension 2 using method 'BalanceSimplest'
Equalizing dimension 3 using method 'BalanceSimplest'
Equalizing dimension 4 using method 'BalanceSimplest'
Equalizing dimension 5 using method 'BalanceSimplest'
Equalizing dimension 6 using method 'BalanceSimplest'
Equalizing dimension 7 using method 'BalanceSimplest'
Equalizing dimension 8 using method 'BalanceSimplest'
Equalizing dimension 9 using method 'BalanceSimplest'
Equalizing dimension 10 using method 'BalanceSimplest'
Equalizing dimension 11 using method 'BalanceSimplest'
Equalizing dimension 12 using method 'BalanceSimplest'
Equalizing dimension 13 using method 'BalanceSimplest'
Equalizing dimension 14 using method 'BalanceSimplest'
Equalizing dimension 15 using method 'BalanceSimplest'
Equalizing dimension 16 using method 'BalanceSimplest'
Equalizing dimension 17 using method 'BalanceSimplest'
Equalizing dimension 18 using method 'BalanceSimplest'
Equalizing dimension 19 using method 'BalanceSimplest'
Equalizing dimension 20 using method 'BalanceSimplest'
Equalizing dimension 21 using method 'BalanceSimplest'
Equalizing dimension 22 using method 'BalanceSimplest'
Equalizing dimension 23 using method 'BalanceSimplest'
Equalizing dimension 24 using method 'BalanceSimplest'
Equalizing dimension 25 using method 'BalanceSimplest'
Equalizing dimension 26 using method 'BalanceSimplest'
Equalizing dimension 27 using method 'BalanceSimplest'
Equalizing dimension 28 using method 'BalanceSimplest'
Equalizing dimension 29 using method 'BalanceSimplest'
Logging changes to AnnData.uns['equalize_image_log']
Histogram equalization completed.
Out[16]:
AnnData object with n_obs × n_vars = 41529 × 17733
    obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster'
    var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
    uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
    obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize'
    layers: 'log_norm'
    obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [17]:
SPIX.pl.image_plot(
    adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding_equalize',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=10,    # Adjust point size here
    origin=True
)
No description has been provided for this image

Parameter Selection¶

In [18]:
results_df = SPIX.op.parameter_selection(
    adata,
    original_moranI,
    n_jobs=32
)
[Parallel(n_jobs=32)]: Using backend LokyBackend with 32 concurrent workers.
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/joblib/externals/loky/process_executor.py:752: UserWarning: A worker stopped while some jobs were given to the executor. This can be caused by a too short worker timeout or by a memory leak.
  warnings.warn(
[Parallel(n_jobs=32)]: Done   8 tasks      | elapsed:   43.5s
[Parallel(n_jobs=32)]: Done  21 tasks      | elapsed:   55.2s
[Parallel(n_jobs=32)]: Done  34 tasks      | elapsed:  1.1min
[Parallel(n_jobs=32)]: Done  49 tasks      | elapsed:  1.4min
[Parallel(n_jobs=32)]: Done  64 tasks      | elapsed:  1.7min
[Parallel(n_jobs=32)]: Done  81 tasks      | elapsed:  2.1min
[Parallel(n_jobs=32)]: Done  96 out of 144 | elapsed:  2.2min remaining:  1.1min
[Parallel(n_jobs=32)]: Done 111 out of 144 | elapsed:  2.4min remaining:   43.1s
[Parallel(n_jobs=32)]: Done 126 out of 144 | elapsed:  2.6min remaining:   21.9s
[Parallel(n_jobs=32)]: Done 141 out of 144 | elapsed:  2.7min remaining:    3.5s
[Parallel(n_jobs=32)]: Done 144 out of 144 | elapsed:  2.8min finished
No description has been provided for this image

Segment Image¶

In [19]:
SPIX.sp.segment_image(
    adata,
    dimensions=list(range(30)),
         embedding='X_embedding_equalize',
         method='leiden_slic',
         resolution=100,
         origin=True,
         compactness=10,
         verbose=True
)
Starting image segmentation using method 'leiden_slic'...
Image segmentation completed.
In [20]:
SPIX.pl.image_plot(
    adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding_segment',
    figsize=(10, 10),    # Adjust figure size here
    scaling_factor=10, # Adjust point size here
    origin=True,
    boundary_linewidth=1,
    brighten_factor=1.8,
    boundary_style='solid',  # 'solid', 'dashed', 'dotted'
    # fixed_boundary_color='Black',
    fill_boundaries=True,
    fill_color='black',
    fill_alpha=0.8,
    plot_boundaries=True,
    alpha=0.9
)
No description has been provided for this image

Make minibulk spots¶

In [21]:
new_adata, superpixel_moranI = SPIX.an.perform_pseudo_bulk_analysis(
    adata,
    segment_key='Segment',
    min_cells=1,
    normalize_total=False, # already normalized data
    log_transform=False, # already normalized data
    moranI_threshold=0.1,
    mode="moran",
    neighbors_kwargs={},        
    autocorr_kwargs={},          
    aggregate_expression=True,   
    add_bulk_layer=True,         
    highly_variable=True,
    perform_pca=True,
    neighbors_params={'n_neighbors': 15} 
)
Starting Pseudo-Bulk Aggregation...
Spatial coordinate aggregation complete.
Aggregated into 1280 segments.
Aggregating expression data...
Expression data aggregation complete.
New AnnData object creation complete.
Performing optional expression data aggregation...
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/anndata/_core/anndata.py:822: UserWarning: 
AnnData expects .obs.index to contain strings, but got values like:
    [0, 1, 2, 3, 4]

    Inferred to be: categorical

  names = self._prep_dim_index(names, "obs")
/home/Data_Drive_8TB/chs1151/.conda/envs/V_t/lib/python3.10/site-packages/anndata/_core/aligned_df.py:68: ImplicitModificationWarning: Transforming to str index.
  warnings.warn("Transforming to str index.", ImplicitModificationWarning)
Expression data aggregation and merging complete.
'bulked' layer addition complete.
Starting preprocessing...
Gene filtering complete: Retained genes present in at least 1 segments.
Spatial neighbors computation complete.
Moran's I calculation complete.
Number of genes with Moran's I >= 0.1: 2769
Highly Variable Genes calculation complete.
PCA complete.
Neighbors computation complete.
Pseudo-Bulk analysis complete.
In [22]:
adata.layers['bulked'].toarray()
Out[22]:
array([[0.        , 0.00632986, 0.00046213, ..., 0.        , 0.00091608,
        0.        ],
       [0.        , 0.04362199, 0.        , ..., 0.        , 0.00127914,
        0.        ],
       [0.00095916, 0.00764041, 0.01655191, ..., 0.        , 0.01600238,
        0.        ],
       ...,
       [0.        , 0.02265343, 0.00669236, ..., 0.        , 0.        ,
        0.        ],
       [0.        , 0.01173735, 0.00892541, ..., 0.        , 0.00897125,
        0.        ],
       [0.        , 0.        , 0.        , ..., 0.        , 0.        ,
        0.        ]], dtype=float32)

Vendiagram¶

In [23]:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib_venn import venn3
from matplotlib_venn import venn2
In [24]:
set_adata = set(original_moranI.index)
set_new_adata2 = set(superpixel_moranI.index)
In [25]:
plt.figure(figsize=(8, 8))
venn = venn2([set_adata,set_new_adata2], 
             ('Original', 'SuperPiexl'))

plt.title('Venn Diagram of Indices with Moran I > 0.1')

plt.show()
No description has been provided for this image
In [26]:
superpixel_unique = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
In [27]:
superpixel_unique
Out[27]:
I pval_norm var_norm pval_norm_fdr_bh
Slc5a7 0.680680 0.000000e+00 0.000241 0.000000e+00
Amotl1 0.675773 0.000000e+00 0.000241 0.000000e+00
Cldn2 0.624873 0.000000e+00 0.000241 0.000000e+00
Prr32 0.615508 0.000000e+00 0.000241 0.000000e+00
Zic4 0.607894 0.000000e+00 0.000241 0.000000e+00
... ... ... ... ...
Tdo2 0.100258 3.822775e-11 0.000241 2.451692e-10
Rtf1 0.100130 4.037604e-11 0.000241 2.588533e-10
Acyp2 0.100100 4.091094e-11 0.000241 2.621878e-10
Olfm2 0.100063 4.156042e-11 0.000241 2.662540e-10
Kif13b 0.100009 4.253098e-11 0.000241 2.723734e-10

2567 rows × 4 columns

In [28]:
original_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
In [29]:
original_unique
Out[29]:
I pval_norm var_norm pval_norm_fdr_bh
Acta2 0.246645 0.0 0.000007 0.0
Cnr1 0.216980 0.0 0.000007 0.0
Gad2 0.143751 0.0 0.000007 0.0
Slc17a8 0.138658 0.0 0.000007 0.0
Gnrh1 0.117854 0.0 0.000007 0.0
Myh11 0.111274 0.0 0.000007 0.0
Vtn 0.110542 0.0 0.000007 0.0
Tagln 0.108735 0.0 0.000007 0.0

Ploting multicale genes¶

Superpixel Unique genes¶

In [30]:
import matplotlib.pyplot as plt

selected_genes = superpixel_unique[superpixel_unique['I'] > 0.5].head(10).index.tolist()

with plt.rc_context({'figure.figsize': [10, 10]}):
    sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100,layer='bulked')
No description has been provided for this image
In [31]:
import matplotlib.pyplot as plt

selected_genes = superpixel_unique[superpixel_unique['I'] > 0.5].head(10).index.tolist()

with plt.rc_context({'figure.figsize': [10, 10]}):
    sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100)
No description has been provided for this image

Original Unique gene¶

In [32]:
import matplotlib.pyplot as plt

selected_genes = original_unique.head(10).index.tolist()

with plt.rc_context({'figure.figsize': [10, 10]}):
    sc.pl.embedding(adata, basis='spatial', color=selected_genes, size=100)
No description has been provided for this image

Ontology Analysis¶

In [33]:
Superpiexl_unique_list = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
Origianl_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
Whole_intersection = superpixel_moranI[superpixel_moranI.index.isin(np.intersect1d(superpixel_moranI.index,original_moranI.index))]
In [35]:
gene_groups = {
    'Superpixel_unique': Superpiexl_unique_list[Superpiexl_unique_list['I']>0.5].index,
    'Original_unique' : Origianl_unique.index,
    'Whole_intersection' : Whole_intersection[Whole_intersection['I']>0.5].index
}

databases = [
    'GO_Biological_Process_2025',
    # 'GO_Molecular_Function_2023',
    # 'GO_Cellular_Component_2023',
    # 'WikiPathways_2024_Mouse',
    # 'Mouse_Gene_Atlas',
    # 'HDSigDB_Mouse_2021',
    # 'KEGG_2019_Mouse',
    # 'KOMP2_Mouse_Phenotypes_2022'
]

# Perform analysis and generate clustermap
enrichment_results = SPIX.an.generate_enrichment_results(gene_groups, databases, verbose=False)

selected_database='GO_Biological_Process_2025'
p_value_threshold = 0.05

heatmap_df = SPIX.an.subset_enrichment_results(
    enrichment_results,
    selected_database=selected_database,
    significance_threshold=p_value_threshold,
    verbose=False
)
In [38]:
import pandas as pd
In [39]:
# Select top 20 rows by PD_enriched (descending order)
top20_SP = heatmap_df.sort_values(by='Superpixel_unique', ascending=False).head(10)

top20_OR = heatmap_df.sort_values(by='Original_unique', ascending=False).head(10)
# Select top 20 rows by CON_enriched (descending order)
top20_IN = heatmap_df.sort_values(by='Whole_intersection', ascending=False).head(10)

# (Optional) Combine both sets, removing duplicates if a Term appears in both
heatmap_df = pd.concat([top20_SP, top20_OR,top20_IN]).drop_duplicates()
In [45]:
clustermap = SPIX.an.create_enrichment_clustermap(
    heatmap_df=heatmap_df,
    selected_database=selected_database,
    # term_pattern='neuro',  # Regex pattern to filter terms
    p_value_threshold=p_value_threshold,
    cmap="Reds",
    figsize=(14, 12),
    metric="euclidean",
    method="average",
    add_annotations=True,
    verbose=True
)
2025-04-09 03:53:46,049 - INFO - Starting clustermap generation.
2025-04-09 03:53:46,050 - INFO - Applying p-value threshold: 1.3010299956639813
2025-04-09 03:53:46,051 - DEBUG - Number of terms after p-value filtering: 25
2025-04-09 03:53:46,051 - DEBUG - Data transformation complete.
2025-04-09 03:53:46,052 - INFO - Generating clustermap.
2025-04-09 03:53:46,272 - INFO - Adding stars for significant p-values.
2025-04-09 03:53:46,282 - INFO - Clustermap generation complete.
No description has been provided for this image

Territory formation with minibulk spots¶

In [47]:
sc.tl.leiden(new_adata, flavor="igraph", n_iterations=2, resolution=1,key_added='spix_leiden')
new_adata.obs['spix_leiden'].nunique()
# tiles_equal
with plt.rc_context({'figure.figsize': [10 ,10]}):
    sc.pl.embedding(new_adata,basis='spatial',color='spix_leiden',size=300,palette=sc.pl.palettes.default_102)
No description has been provided for this image

Transfer Territories to entire spots and compare with nonspatial leiden clustering¶

In [48]:
new_adata.obs.index = new_adata.obs.index.astype('int64')
adata.obs['spix_leiden'] = adata.obs['Segment'].map(new_adata.obs['spix_leiden'])
new_adata.obs.index = new_adata.obs.index.astype('str')
In [49]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
    sc.pl.embedding(adata,basis='spatial',color=['leiden','spix_leiden','cluster'],size=50,palette=sc.pl.palettes.default_102)
No description has been provided for this image

Experimental :: Territory formation with two time supepixels¶

In [50]:
new_adata = SPIX.tm.generate_embeddings(
    new_adata,
    dim_reduction='PCA',
    normalization='none', # already normalized data
    dimensions=30,
    nfeatures=2000,
    n_jobs=16,
    filter_grid=1,
    filter_threshold=0.98,
    tensor_resolution=1,
    chunksize=3000,
    verbose=True
    )
2025-04-09 03:56:37,018 - INFO - Starting generate_embeddings...
2025-04-09 03:56:37,019 - INFO - Tiles not found. Generating tiles...
2025-04-09 03:56:37,020 - INFO - Starting generate_tiles...
2025-04-09 03:56:37,021 - INFO - Original coordinates: (1280, 2)
2025-04-09 03:56:37,021 - INFO - Performing Voronoi tessellation...
2025-04-09 03:56:37,030 - INFO - Voronoi tessellation completed.
2025-04-09 03:56:37,030 - INFO - Filtering tiles...
Calculating Voronoi region areas: 100%|██████████| 1280/1280 [00:00<00:00, 16928.78it/s]
Filtering tiles by area: 100%|██████████| 1246/1246 [00:00<00:00, 2207901.47it/s]
2025-04-09 03:56:37,111 - INFO - Filtered regions: 1221, Filtered coordinates: (1221, 2)
2025-04-09 03:56:37,111 - INFO - Rasterising tiles...
Rasterising tiles: 100%|██████████| 1221/1221 [00:07<00:00, 156.54it/s]
2025-04-09 03:56:51,562 - INFO - Rasterisation completed. Number of tiles: 17728332
2025-04-09 03:56:51,563 - INFO - Tiles have been stored in adata.uns['tiles'].
2025-04-09 03:56:52,453 - INFO - adata has been subset from 1280 to 1221 observations based on filtered tiles.
2025-04-09 03:56:52,454 - INFO - generate_tiles completed.
2025-04-09 03:56:52,455 - INFO - Processing counts...
2025-04-09 03:56:52,456 - INFO - Processing counts with method: none
2025-04-09 03:56:52,625 - INFO - Counts processing completed.
2025-04-09 03:56:52,632 - INFO - Embedding latent space...
2025-04-09 03:56:52,633 - INFO - Embedding latent space using PCA...
2025-04-09 03:56:52,986 - INFO - Latent space embedding completed.
2025-04-09 03:56:52,989 - INFO - generate_embeddings completed.
In [51]:
SPIX.pl.image_plot(
    new_adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=50,    # Adjust point size here
    origin=True
)
No description has been provided for this image
In [52]:
SPIX.pl.image_plot(
    new_adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=0.1,    # Adjust point size here
    origin=False
)
No description has been provided for this image
In [53]:
SPIX.ip.smooth_image(
    new_adata,
    dimensions = list(range(30)),
    sigma=20,
    n_jobs=30,
    multi_method='loky'
)
2025-04-09 03:57:28,392 - INFO - Starting smooth_image...
2025-04-09 03:57:28,394 - INFO - Using embedding 'X_embedding' with shape (1221, 30).
2025-04-09 03:57:28,659 - INFO - Shifting coordinates by (-364, -125) to start from 0.
2025-04-09 03:57:29,194 - INFO - Image size: width=6877, height=6116
2025-04-09 03:57:29,195 - INFO - Starting parallel processing of dimensions...
Filling NaNs:   0%|          | 0/30 [00:00<?, ?it/s]
  0%|          | 0/30 [00:00<?, ?it/s]
2025-04-09 03:57:51,946 - INFO - Filling NaNs for dimension 0...
2025-04-09 03:57:52,799 - INFO - Filling NaNs for dimension 1...
2025-04-09 03:57:53,391 - INFO - Filling NaNs for dimension 2...
2025-04-09 03:57:54,406 - INFO - Filling NaNs for dimension 3...
2025-04-09 03:57:54,875 - INFO - Filling NaNs for dimension 4...
2025-04-09 03:57:55,864 - INFO - Filling NaNs for dimension 5...
2025-04-09 03:57:56,655 - INFO - Filling NaNs for dimension 6...
2025-04-09 03:57:57,682 - INFO - Filling NaNs for dimension 7...
2025-04-09 03:57:57,827 - INFO - Filling NaNs for dimension 8...
2025-04-09 03:57:58,936 - INFO - Filling NaNs for dimension 9...
2025-04-09 03:58:00,056 - INFO - Filling NaNs for dimension 10...
2025-04-09 03:58:00,568 - INFO - Filling NaNs for dimension 11...
2025-04-09 03:58:01,463 - INFO - Filling NaNs for dimension 12...
2025-04-09 03:58:01,497 - INFO - Filling NaNs for dimension 13...
2025-04-09 03:58:02,695 - INFO - Filling NaNs for dimension 14...
2025-04-09 03:58:03,079 - INFO - Filling NaNs for dimension 15...
2025-04-09 03:58:03,923 - INFO - Filling NaNs for dimension 16...
2025-04-09 03:58:05,046 - INFO - Filling NaNs for dimension 17...
2025-04-09 03:58:05,956 - INFO - Filling NaNs for dimension 18...
2025-04-09 03:58:06,441 - INFO - Filling NaNs for dimension 19...
2025-04-09 03:58:06,922 - INFO - Filling NaNs for dimension 20...
2025-04-09 03:58:07,742 - INFO - Filling NaNs for dimension 21...
2025-04-09 03:58:08,855 - INFO - Filling NaNs for dimension 22...
2025-04-09 03:58:09,381 - INFO - Filling NaNs for dimension 23...
2025-04-09 03:58:10,224 - INFO - Filling NaNs for dimension 24...
2025-04-09 03:58:10,543 - INFO - Filling NaNs for dimension 25...
2025-04-09 03:58:11,590 - INFO - Filling NaNs for dimension 26...
2025-04-09 03:58:12,146 - INFO - Filling NaNs for dimension 27...
2025-04-09 03:58:12,697 - INFO - Filling NaNs for dimension 28...
2025-04-09 03:58:13,581 - INFO - Filling NaNs for dimension 29...
Filling NaNs:   0%|          | 0/30 [01:00<?, ?it/s]
Smoothing dimensions:   0%|          | 0/30 [00:00<?, ?it/s]
  0%|          | 0/30 [00:00<?, ?it/s]
2025-04-09 03:58:30,916 - INFO - Smoothing for dimension 0...
2025-04-09 03:58:30,978 - INFO - Iteration 1/1 for dimension 0.
2025-04-09 03:58:31,911 - INFO - Smoothing for dimension 1...
2025-04-09 03:58:31,983 - INFO - Iteration 1/1 for dimension 1.
2025-04-09 03:58:32,902 - INFO - Smoothing for dimension 2...
2025-04-09 03:58:32,965 - INFO - Iteration 1/1 for dimension 2.
2025-04-09 03:58:33,939 - INFO - Smoothing for dimension 3...
2025-04-09 03:58:34,076 - INFO - Iteration 1/1 for dimension 3.
2025-04-09 03:58:35,018 - INFO - Smoothing for dimension 4...
2025-04-09 03:58:35,074 - INFO - Iteration 1/1 for dimension 4.
2025-04-09 03:58:36,064 - INFO - Smoothing for dimension 5...
2025-04-09 03:58:36,138 - INFO - Iteration 1/1 for dimension 5.
2025-04-09 03:58:37,111 - INFO - Smoothing for dimension 6...
2025-04-09 03:58:37,194 - INFO - Iteration 1/1 for dimension 6.
2025-04-09 03:58:38,179 - INFO - Smoothing for dimension 7...
2025-04-09 03:58:38,234 - INFO - Iteration 1/1 for dimension 7.
2025-04-09 03:58:39,179 - INFO - Smoothing for dimension 8...
2025-04-09 03:58:39,251 - INFO - Iteration 1/1 for dimension 8.
2025-04-09 03:58:40,409 - INFO - Smoothing for dimension 9...
2025-04-09 03:58:40,485 - INFO - Iteration 1/1 for dimension 9.
2025-04-09 03:58:41,394 - INFO - Smoothing for dimension 10...
2025-04-09 03:58:41,532 - INFO - Iteration 1/1 for dimension 10.
2025-04-09 03:58:42,612 - INFO - Smoothing for dimension 11...
2025-04-09 03:58:42,693 - INFO - Iteration 1/1 for dimension 11.
2025-04-09 03:58:43,688 - INFO - Smoothing for dimension 12...
2025-04-09 03:58:43,744 - INFO - Iteration 1/1 for dimension 12.
2025-04-09 03:58:44,856 - INFO - Smoothing for dimension 13...
2025-04-09 03:58:44,932 - INFO - Iteration 1/1 for dimension 13.
2025-04-09 03:58:45,822 - INFO - Smoothing for dimension 14...
2025-04-09 03:58:45,939 - INFO - Iteration 1/1 for dimension 14.
2025-04-09 03:58:46,964 - INFO - Smoothing for dimension 15...
2025-04-09 03:58:47,019 - INFO - Iteration 1/1 for dimension 15.
2025-04-09 03:58:47,942 - INFO - Smoothing for dimension 16...
2025-04-09 03:58:48,002 - INFO - Iteration 1/1 for dimension 16.
2025-04-09 03:58:49,205 - INFO - Smoothing for dimension 17...
2025-04-09 03:58:49,325 - INFO - Iteration 1/1 for dimension 17.
2025-04-09 03:58:50,171 - INFO - Smoothing for dimension 18...
2025-04-09 03:58:50,253 - INFO - Iteration 1/1 for dimension 18.
2025-04-09 03:58:51,365 - INFO - Smoothing for dimension 19...
2025-04-09 03:58:51,456 - INFO - Iteration 1/1 for dimension 19.
2025-04-09 03:58:52,244 - INFO - Smoothing for dimension 20...
2025-04-09 03:58:52,300 - INFO - Iteration 1/1 for dimension 20.
2025-04-09 03:58:53,424 - INFO - Smoothing for dimension 21...
2025-04-09 03:58:53,480 - INFO - Iteration 1/1 for dimension 21.
2025-04-09 03:58:54,434 - INFO - Smoothing for dimension 22...
2025-04-09 03:58:54,493 - INFO - Iteration 1/1 for dimension 22.
2025-04-09 03:58:55,616 - INFO - Smoothing for dimension 23...
2025-04-09 03:58:55,676 - INFO - Iteration 1/1 for dimension 23.
2025-04-09 03:58:56,637 - INFO - Smoothing for dimension 24...
2025-04-09 03:58:56,717 - INFO - Iteration 1/1 for dimension 24.
2025-04-09 03:58:57,774 - INFO - Smoothing for dimension 25...
2025-04-09 03:58:57,832 - INFO - Iteration 1/1 for dimension 25.
2025-04-09 03:58:58,722 - INFO - Smoothing for dimension 26...
2025-04-09 03:58:58,777 - INFO - Iteration 1/1 for dimension 26.
2025-04-09 03:58:59,925 - INFO - Smoothing for dimension 27...
2025-04-09 03:59:00,005 - INFO - Iteration 1/1 for dimension 27.
2025-04-09 03:59:01,116 - INFO - Smoothing for dimension 28...
2025-04-09 03:59:01,172 - INFO - Iteration 1/1 for dimension 28.
2025-04-09 03:59:02,109 - INFO - Smoothing for dimension 29...
2025-04-09 03:59:02,168 - INFO - Iteration 1/1 for dimension 29.
Smoothing dimensions:   0%|          | 0/30 [00:42<?, ?it/s]
2025-04-09 03:59:11,532 - INFO - Applying Min-Max scaling to the smoothed embeddings.
2025-04-09 03:59:11,537 - INFO - Smoothed embeddings stored in adata.obsm['X_embedding_smooth'].
2025-04-09 03:59:11,538 - INFO - Smoothing completed and embeddings updated in AnnData object.
Out[53]:
AnnData object with n_obs × n_vars = 1221 × 17733
    obs: 'spix_leiden'
    var: 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm'
    uns: 'spatial_neighbors', 'moranI', 'hvg', 'pca', 'neighbors', 'spix_leiden', 'spix_leiden_colors', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict'
    obsm: 'spatial', 'X_pca', 'X_embedding', 'X_embedding_smooth'
    varm: 'PCs'
    layers: 'counts', 'log_norm'
    obsp: 'spatial_connectivities', 'spatial_distances', 'distances', 'connectivities'
In [54]:
SPIX.pl.image_plot(
    new_adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding_smooth',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=80,    # Adjust point size here
    origin=True
)
No description has been provided for this image
In [55]:
SPIX.ip.equalize_image(
    new_adata,
    dimensions=list(range(30)),
    embedding='X_embedding_smooth',
    sleft=5,sright=5)
Starting equalization...
Equalizing dimension 0 using method 'BalanceSimplest'
Equalizing dimension 1 using method 'BalanceSimplest'
Equalizing dimension 2 using method 'BalanceSimplest'
Equalizing dimension 3 using method 'BalanceSimplest'
Equalizing dimension 4 using method 'BalanceSimplest'
Equalizing dimension 5 using method 'BalanceSimplest'
Equalizing dimension 6 using method 'BalanceSimplest'
Equalizing dimension 7 using method 'BalanceSimplest'
Equalizing dimension 8 using method 'BalanceSimplest'
Equalizing dimension 9 using method 'BalanceSimplest'
Equalizing dimension 10 using method 'BalanceSimplest'
Equalizing dimension 11 using method 'BalanceSimplest'
Equalizing dimension 12 using method 'BalanceSimplest'
Equalizing dimension 13 using method 'BalanceSimplest'
Equalizing dimension 14 using method 'BalanceSimplest'
Equalizing dimension 15 using method 'BalanceSimplest'
Equalizing dimension 16 using method 'BalanceSimplest'
Equalizing dimension 17 using method 'BalanceSimplest'
Equalizing dimension 18 using method 'BalanceSimplest'
Equalizing dimension 19 using method 'BalanceSimplest'
Equalizing dimension 20 using method 'BalanceSimplest'
Equalizing dimension 21 using method 'BalanceSimplest'
Equalizing dimension 22 using method 'BalanceSimplest'
Equalizing dimension 23 using method 'BalanceSimplest'
Equalizing dimension 24 using method 'BalanceSimplest'
Equalizing dimension 25 using method 'BalanceSimplest'
Equalizing dimension 26 using method 'BalanceSimplest'
Equalizing dimension 27 using method 'BalanceSimplest'
Equalizing dimension 28 using method 'BalanceSimplest'
Equalizing dimension 29 using method 'BalanceSimplest'
Logging changes to AnnData.uns['equalize_image_log']
Histogram equalization completed.
Out[55]:
AnnData object with n_obs × n_vars = 1221 × 17733
    obs: 'spix_leiden'
    var: 'n_cells', 'highly_variable', 'means', 'dispersions', 'dispersions_norm'
    uns: 'spatial_neighbors', 'moranI', 'hvg', 'pca', 'neighbors', 'spix_leiden', 'spix_leiden_colors', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
    obsm: 'spatial', 'X_pca', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize'
    varm: 'PCs'
    layers: 'counts', 'log_norm'
    obsp: 'spatial_connectivities', 'spatial_distances', 'distances', 'connectivities'
In [56]:
SPIX.pl.image_plot(
    new_adata,
    dimensions=[0, 1, 2],
    embedding='X_embedding_equalize',
    figsize=(10, 10),     # Adjust figure size here
    scaling_factor=80,    # Adjust point size here
    origin=True
)
No description has been provided for this image
In [57]:
SPIX.sp.segment_image(
    new_adata,
    dimensions=list(range(30)),
         embedding='X_embedding_equalize',
         method='leiden_slic',
         resolution=1,
         origin=True,
         compactness=0.1,
         verbose=True
     )
Starting image segmentation using method 'leiden_slic'...
Image segmentation completed.
In [58]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
    sc.pl.embedding(new_adata,basis='spatial',color='Segment',size=300,palette=sc.pl.palettes.default_102)
No description has been provided for this image
In [ ]:
 

Transfer Territories to entrie spots and compare with others¶

In [59]:
new_adata.obs.index = new_adata.obs.index.astype('int64')
adata.obs['bulked_segment'] = adata.obs['Segment'].map(new_adata.obs['Segment'])
new_adata.obs.index = new_adata.obs.index.astype('str')
In [60]:
with plt.rc_context({'figure.figsize': [10 ,10]}):
    sc.pl.embedding(adata,basis='spatial',color=['leiden','spix_leiden','bulked_segment','cluster'],size=30,palette=sc.pl.palettes.default_102)
No description has been provided for this image
In [ ]:
 

Compare DEGs¶

Supepixel leiden territories¶

In [146]:
sc.tl.rank_genes_groups(adata,groupby='spix_leiden',pts=True,method='wilcoxon')
In [147]:
sc.tl.filter_rank_genes_groups(adata,groupby='spix_leiden',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [148]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 15
WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different.
categories: 0, 1, 2, etc.
var_group_labels: 0, 1, 2, etc.
No description has been provided for this image

two time Supepixel territories¶

In [166]:
adata.obs['bulked_segment'] = adata.obs['bulked_segment'].astype(str)
In [167]:
sc.tl.rank_genes_groups(adata,groupby='bulked_segment',pts=True,method='wilcoxon')
... storing 'bulked_segment' as categorical
In [171]:
sc.tl.filter_rank_genes_groups(adata,groupby='bulked_segment',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [172]:
sc.tl.dendrogram(adata,groupby='bulked_segment')
In [173]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 4
WARNING: No genes found for group 13
WARNING: No genes found for group nan
WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different.
categories: 0, 1, 2, etc.
var_group_labels: 0, 1, 2, etc.
No description has been provided for this image

Nonspatial leiden clusters¶

In [149]:
sc.tl.rank_genes_groups(adata,groupby='leiden',pts=True,method='wilcoxon')
In [150]:
sc.tl.filter_rank_genes_groups(adata,groupby='leiden',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [151]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: No genes found for group 1
WARNING: No genes found for group 2
WARNING: Groups are not reordered because the `groupby` categories and the `var_group_labels` are different.
categories: 0, 1, 2, etc.
var_group_labels: 0, 3, 4, etc.
No description has been provided for this image

Annotation DEGs¶

In [152]:
sc.tl.rank_genes_groups(adata,groupby='cluster',pts=True,method='wilcoxon')
In [153]:
sc.tl.filter_rank_genes_groups(adata,groupby='cluster',min_fold_change=2,max_out_group_fraction=0.1,min_in_group_fraction=0.1)
In [154]:
sc.pl.rank_genes_groups_dotplot(adata,key='rank_genes_groups_filtered')
WARNING: dendrogram data not found (using key=dendrogram_cluster). Running `sc.tl.dendrogram` with default parameters. For fine tuning it is recommended to run `sc.tl.dendrogram` independently.
No description has been provided for this image
In [46]:
adata
Out[46]:
AnnData object with n_obs × n_vars = 41529 × 17733
    obs: 'barcode', 'x', 'y', 'n_genes_by_counts', 'log1p_n_genes_by_counts', 'total_counts', 'log1p_total_counts', 'pct_counts_in_top_50_genes', 'pct_counts_in_top_100_genes', 'pct_counts_in_top_200_genes', 'pct_counts_in_top_500_genes', 'total_counts_MT', 'log1p_total_counts_MT', 'pct_counts_MT', 'n_counts', 'leiden', 'cluster', 'Segment'
    var: 'MT', 'n_cells_by_counts', 'mean_counts', 'log1p_mean_counts', 'pct_dropout_by_counts', 'total_counts', 'log1p_total_counts', 'n_cells', 'highly_variable', 'highly_variable_rank', 'means', 'variances', 'variances_norm'
    uns: 'cluster_colors', 'hvg', 'leiden', 'leiden_colors', 'neighbors', 'pca', 'spatial_neighbors', 'umap', 'moranI', 'tiles', 'tiles_generated', 'embedding_method', 'tensor_resolution', 'na_filled_images_dict', 'smoothed_images_dict', 'equalize_image_log'
    obsm: 'X_pca', 'X_umap', 'deconvolution_results', 'spatial', 'X_embedding', 'X_embedding_smooth', 'X_embedding_equalize', 'X_embedding_segment', 'X_embedding_scaled_for_segment'
    layers: 'log_norm', 'bulked'
    obsp: 'connectivities', 'distances', 'spatial_connectivities', 'spatial_distances'
In [ ]:
 

Ontology Analysis¶

In [33]:
Superpiexl_unique_list = superpixel_moranI[superpixel_moranI.index.isin(np.setdiff1d(superpixel_moranI.index,original_moranI.index))]
Origianl_unique = original_moranI[original_moranI.index.isin(np.setdiff1d(original_moranI.index,superpixel_moranI.index))]
Whole_intersection = superpixel_moranI[superpixel_moranI.index.isin(np.intersect1d(superpixel_moranI.index,original_moranI.index))]
In [35]:
gene_groups = {
    'Superpixel_unique': Superpiexl_unique_list[Superpiexl_unique_list['I']>0.5].index,
    'Original_unique' : Origianl_unique.index,
    'Whole_intersection' : Whole_intersection[Whole_intersection['I']>0.5].index
}

databases = [
    'GO_Biological_Process_2025',
    # 'GO_Molecular_Function_2023',
    # 'GO_Cellular_Component_2023',
    # 'WikiPathways_2024_Mouse',
    # 'Mouse_Gene_Atlas',
    # 'HDSigDB_Mouse_2021',
    # 'KEGG_2019_Mouse',
    # 'KOMP2_Mouse_Phenotypes_2022'
]

# Perform analysis and generate clustermap
enrichment_results = SPIX.an.generate_enrichment_results(gene_groups, databases, verbose=False)

selected_database='GO_Biological_Process_2025'
p_value_threshold = 0.05

heatmap_df = SPIX.an.subset_enrichment_results(
    enrichment_results,
    selected_database=selected_database,
    significance_threshold=p_value_threshold,
    verbose=False
)
In [38]:
import pandas as pd
In [39]:
# Select top 20 rows by PD_enriched (descending order)
top20_SP = heatmap_df.sort_values(by='Superpixel_unique', ascending=False).head(10)

top20_OR = heatmap_df.sort_values(by='Original_unique', ascending=False).head(10)
# Select top 20 rows by CON_enriched (descending order)
top20_IN = heatmap_df.sort_values(by='Whole_intersection', ascending=False).head(10)

# (Optional) Combine both sets, removing duplicates if a Term appears in both
heatmap_df = pd.concat([top20_SP, top20_OR,top20_IN]).drop_duplicates()
In [45]:
clustermap = SPIX.an.create_enrichment_clustermap(
    heatmap_df=heatmap_df,
    selected_database=selected_database,
    # term_pattern='neuro',  # Regex pattern to filter terms
    p_value_threshold=p_value_threshold,
    cmap="Reds",
    figsize=(14, 12),
    metric="euclidean",
    method="average",
    add_annotations=True,
    verbose=True
)
2025-04-09 03:53:46,049 - INFO - Starting clustermap generation.
2025-04-09 03:53:46,050 - INFO - Applying p-value threshold: 1.3010299956639813
2025-04-09 03:53:46,051 - DEBUG - Number of terms after p-value filtering: 25
2025-04-09 03:53:46,051 - DEBUG - Data transformation complete.
2025-04-09 03:53:46,052 - INFO - Generating clustermap.
2025-04-09 03:53:46,272 - INFO - Adding stars for significant p-values.
2025-04-09 03:53:46,282 - INFO - Clustermap generation complete.
No description has been provided for this image
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]:
 
In [ ]: